package com.example.user_manage.Component;

import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.example.user_manage.constants.TempConstant;
import com.example.user_manage.dto.UserResponseDTO;
import com.example.user_manage.entity.User;
import com.example.user_manage.util.EntityOrDTOUtil;
import com.example.user_manage.util.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 身份验证成功处理器
 */
@Component
@AllArgsConstructor
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
    /**
     * redis数据库模版对象
     */
    private final RedisTemplate<String,Object> redisTemplate;

    /**
     * 验证成功后调用此方法
     * @param request 请求对象
     * @param response 响应对象
     * @param authentication 身份验证对象
     * @throws IOException IO异常
     */
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request
            ,HttpServletResponse response
            ,Authentication authentication) throws IOException {
        //指定响应的字符集编码格式
        response.setContentType("application/json;charset=utf-8");

        //获取验证后的用户信息
        User user = (User) authentication.getPrincipal();
        //将用户信息转换成用户号响应DTO
        UserResponseDTO userResponseDTO = EntityOrDTOUtil.toUserResponseDTO(user);
        //配置json的时间格式
        JSONConfig jsonConfig = JSONConfig.create().setDateFormat("yyyy-MM-dd HH:mm:ss");
        //将用户响应DTO转换成json格式
        String userResponseDTOStr = JSONUtil.toJsonStr(userResponseDTO, jsonConfig);

        //创建jwt负载
        Map<String,Object> payLoad = new HashMap<>();
        payLoad.put("user",userResponseDTO);
        //创建jwt
        String jwt = JWTUtil.createToken(payLoad, JwtUtil.secret.getBytes(StandardCharsets.UTF_8));
        //将jwt存入redis
        redisTemplate.opsForHash().put(TempConstant.REDIS_TOKEN_KEY
                ,user.getId().toString()
                ,jwt);
        //设置token存放时间为20秒
        redisTemplate.expire(TempConstant.REDIS_TOKEN_KEY, Duration.ofSeconds(1200));

        //返回用户信息
        response.getWriter().write(userResponseDTOStr);
        //返回jwt
        response.getWriter().write(jwt);
    }
}
